﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Popups;

namespace DoNetDrive.Connector.WindowsBLE
{
    /// <summary>
    /// 蓝牙BLE搜素服务
    /// </summary>
    public class BLESearchService : IDisposable
    {
        private static object lockedobj = new object();


        public static Dictionary<ulong, BluetoothLEDevice> BLEDevices { get; private set; }
        public static Dictionary<string, List<GattCharacteristic>> BLECharacteristics { get; private set; }

        static BLESearchService()
        {
            BLEDevices = new Dictionary<ulong, BluetoothLEDevice>();
            BLECharacteristics = new Dictionary<string, List<GattCharacteristic>>();

        }

        public static void AddBLEDevice(BluetoothLEDevice ble)
        {
            BLEDevices[ble.BluetoothAddress] = ble;
            ble.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;
        }



        private static void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
        {
            if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected)
            {
                if( BLEDevices.ContainsKey(sender.BluetoothAddress))
                {
                    BLEDevices.Remove(sender.BluetoothAddress);

                    var sKeys = BLECharacteristics.Keys.Where(x => x.StartsWith(sender.BluetoothAddress.ToString()));
                    foreach (var key in sKeys) {
                        BLECharacteristics.Remove(key);
                    }
                }
            }
        }


        public static void AddBLECharacteristic(BluetoothLEDevice ble, GattDeviceService service, List<GattCharacteristic> Characteristics)
        {
            string sKey = $"{ble.BluetoothAddress}_{service.Uuid}";
            BLECharacteristics[sKey] = Characteristics;
        }

        public static List<GattCharacteristic> GetBLECharacteristicByCatch(BluetoothLEDevice ble, GattDeviceService service)
        {
            string sKey = $"{ble.BluetoothAddress}_{service.Uuid}";
            if (BLECharacteristics.ContainsKey(sKey))
            {
                return BLECharacteristics[sKey];
            }
            else
                return null;
        }



        public Action<ulong, string> DeviceWatcherChanged;
        /// <summary>
        /// 搜索蓝牙设备对象
        /// </summary>
        //private DeviceWatcher deviceWatcher;
        private BluetoothLEAdvertisementWatcher deviceWatcher;

        private bool _isStop = true;


        public BLESearchService(Action<ulong, string> callblack)
        {
            DeviceWatcherChanged = callblack;
            _isStop = true;
        }

        // <summary>
        /// 搜索蓝牙设备
        /// </summary>
        public bool StartBleDeviceWatcher()
        {
            StopBleDeviceWatcher();

            try
            {
                deviceWatcher = new BluetoothLEAdvertisementWatcher();
                deviceWatcher.ScanningMode = BluetoothLEScanningMode.Active;//指定活动扫描模式。 这表示将从平台发送扫描请求数据包，以主动查询更多 BluetoothLEAdvertisementType.ScanResponse 类型的广告数据。

                //信号强度过滤
                deviceWatcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;
                deviceWatcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;
                deviceWatcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
                deviceWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);
                deviceWatcher.Received += DeviceWatcher_Received;
                deviceWatcher.Start();
            }
            catch (Exception)
            {

                return false;
            }
            _isStop = false;



            return true;
        }

        private void DeviceWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
        {
            lock (lockedobj)
            {
                if (_isStop) return;
                DeviceWatcherChanged?.Invoke(args.BluetoothAddress, args.Advertisement.LocalName);
            }

        }
        /// <summary>
        /// 停止搜索蓝牙
        /// </summary>
        public void StopBleDeviceWatcher()
        {
            Dispose();
        }



        /// <summary>
        /// 通过蓝牙地址获取蓝牙对象
        /// </summary>
        /// <param name="bleAddress"></param>
        /// <returns></returns>
        public static async Task<BluetoothLEDevice> FromBluetoothAddressAsync(ulong bleAddress)
        {
            return await BluetoothLEDevice.FromBluetoothAddressAsync(bleAddress);
        }

        public void Dispose()
        {
            _isStop = true;
            if (deviceWatcher != null)
            {
                deviceWatcher.Stop();
            }
            deviceWatcher = null;
        }
    }
}
